
package com.be.beadmin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.druid.util.StringUtils;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.service.dto.input.SerialNumberDto;
import com.be.beadmin.service.dto.output.SerialNumberEx;
import com.be.beadmin.service.entity.SerialNumber;
import com.be.beadmin.service.entity.SerialNumberItem;
import com.be.beadmin.service.entity.SerialNumber_;
import com.be.beadmin.service.mapper.SerialNumberMapper;
import com.be.beadmin.service.mapper.SerialNumberMapperEx;
import com.be.beadmin.service.repository.SerialNumberItemRepository;
import com.be.beadmin.service.repository.SerialNumberRepository;
import com.be.beadmin.service.service.SerialNumberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
* @description 服务实现
* @author chenwei
* @date 2023-01-16
**/
@Service
public class SerialNumberServiceImpl implements SerialNumberService {

    @Autowired
    private  SerialNumberRepository serialNumberRepository;

    @Autowired
    private SerialNumberItemRepository serialNumberItemRepository;


    @Autowired
    private  SerialNumberMapper serialNumberMapper;
    @Autowired
    private  SerialNumberMapperEx serialNumberExMapper;

    @Override
    public Page<SerialNumberEx> getSerialNumberByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<SerialNumber> page = serialNumberRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(SerialNumber_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate pre3 = criteriaBuilder.equal(root.get(SerialNumber_.invisible), 0); //过滤为0
                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(SerialNumber_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<SerialNumberEx> page1 = page.map(serialNumberExMapper::toEntity);
            return page1;

    }

    @Override
    public void addSerialNumber(SerialNumberDto serialNumberDto) {
            SerialNumber result = serialNumberRepository.findSerialNumberByIdAndDelete(serialNumberDto.getId(), 0);
            if(ObjectUtil.isNotEmpty(result)) {
                throw new BeadminException("SerialNumber不存在,请重新查询");
            }
            SerialNumber serialNumber = serialNumberMapper.toEntity(serialNumberDto);
            serialNumberRepository.save(serialNumber);
    }

    @Override
    public void updateSerialNumber(SerialNumberDto serialNumberDto) {
            SerialNumber serialNumber = serialNumberRepository.findSerialNumberById(serialNumberDto.getId());
            serialNumber = serialNumberMapper.toEntity(serialNumberDto);
            serialNumberRepository.save(serialNumber);
    }


    @Override
    public void delSerialNumber(String id) {
        SerialNumber serialNumber = serialNumberRepository.findSerialNumberById(id);
        serialNumber.setDelete(1);
        serialNumberRepository.save(serialNumber);
    }

    @Override
    public void delSerialNumbers (List<String> ids) { }

    @Override
    public String getNextSnByCode(String code) {
        SerialNumber serialNumber = serialNumberRepository.findSerialNumberByCodeAndDelete(code, 0);
        Integer maxNumber = 0;
        String preValue = "";

        if(ObjectUtil.isEmpty(serialNumber)) {
            return null;
        }

        List<SerialNumberItem> serialNumberItems =
                serialNumberItemRepository.findSerialNumberItemsByDeleteAndSerialNumberOrderBySort(0, serialNumber);



        Optional<SerialNumberItem> optionalSerialNumberItem = serialNumberItems.stream().filter(item -> item.getType() == 1 && item.getFollowDate())
                .findFirst();
        SerialNumberItem serialNumberItem = new SerialNumberItem();
        // 保存当前的最大值和时间
        if (!optionalSerialNumberItem.isPresent()) {
            // 如果是空就不管
            maxNumber = serialNumber.getMaxNumber() + 1;
        } else {
            serialNumberItem = optionalSerialNumberItem.get();
            if(checkDateChange(serialNumberItem.getRule(), serialNumber.getPreRuleValue())) {
                maxNumber = 1;
            } else {
                maxNumber = serialNumber.getMaxNumber() + 1;
            }

            Date currentTime =  new Date();
            SimpleDateFormat sdf = new SimpleDateFormat(serialNumberItem.getRule());
            String currentValue = sdf.format(currentTime);
            preValue = currentValue;


        }

        StringBuilder stringBuilder = new StringBuilder();
        // 拼接
        for (SerialNumberItem item :
                serialNumberItems) {
            buildSerialString(stringBuilder, item.getType(), item.getRule(), serialNumber.getLinkSymbol());
        }
        stringBuilder.append(String.format("%0"+serialNumber.getCodeCnt()+"d",Integer.valueOf(maxNumber)));

        serialNumber.setMaxNumber(maxNumber);
        serialNumber.setPreRuleValue(preValue);
        serialNumberRepository.save(serialNumber);
        return stringBuilder.toString();

    }

    @Override
    public String getNextSnByCodeNotSave(String code) {
        SerialNumber serialNumber = serialNumberRepository.findSerialNumberByCodeAndDelete(code, 0);
        Integer maxNumber = 0;
        String preValue = "";

        if(ObjectUtil.isEmpty(serialNumber)) {
            return null;
        }

        List<SerialNumberItem> serialNumberItems =
                serialNumberItemRepository.findSerialNumberItemsByDeleteAndSerialNumberOrderBySort(0, serialNumber);



        Optional<SerialNumberItem> optionalSerialNumberItem = serialNumberItems.stream().filter(item -> item.getType() == 1 && item.getFollowDate())
                .findFirst();
        SerialNumberItem serialNumberItem = new SerialNumberItem();
        // 保存当前的最大值和时间
        if (!optionalSerialNumberItem.isPresent()) {
            // 如果是空就不管
            maxNumber = serialNumber.getMaxNumber() + 1;
        } else {
            serialNumberItem = optionalSerialNumberItem.get();
            if(checkDateChange(serialNumberItem.getRule(), serialNumber.getPreRuleValue())) {
                maxNumber = 1;
            } else {
                maxNumber = serialNumber.getMaxNumber() + 1;
            }

            Date currentTime =  new Date();
            SimpleDateFormat sdf = new SimpleDateFormat(serialNumberItem.getRule());
            String currentValue = sdf.format(currentTime);
            preValue = currentValue;


        }

        StringBuilder stringBuilder = new StringBuilder();
        // 拼接
        for (SerialNumberItem item :
                serialNumberItems) {
            buildSerialString(stringBuilder, item.getType(), item.getRule(), serialNumber.getLinkSymbol());
        }
        stringBuilder.append(String.format("%0"+serialNumber.getCodeCnt()+"d",Integer.valueOf(maxNumber)));

//        serialNumber.setMaxNumber(maxNumber);
//        serialNumber.setPreRuleValue(preValue);
//        serialNumberRepository.save(serialNumber);
        return stringBuilder.toString();

    }
    @Override
    public List<String> getRangeSnByCode(String code, Integer range) {
        return null;
    }

    /**
     * 删除指定项目下的所有流水编码
     *
     * @param infoId
     */
    @Override
    public void deleteSerialNumberByInfo(String infoId) {
        serialNumberRepository.deleteSerialNumberByCode(infoId+"%");
    }


    public Boolean checkDateChange(String rule, String preValue) {
        // 获取当前时间
        Date currentTime =  new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(rule);

        String currentValue = sdf.format(currentTime);
        if (currentValue.equals(preValue)) {
            return false;
        } else {
            return true;
        }
    }


    private void buildSerialString(StringBuilder res, Integer type, String rule, String linkSymbol) {
        if (StringUtils.isEmpty(rule)) {
            return;
        }
        if (type == 0) {
            if(StringUtils.isEmpty(linkSymbol)) {
                res.append(rule);
            } else {
                res.append(rule + linkSymbol);
            }

        }
        if (type ==1) {

            Date currentTime =  new Date();
            SimpleDateFormat sdf = new SimpleDateFormat(rule);

            String currentValue = sdf.format(currentTime);
            if (StringUtils.isEmpty(linkSymbol)) {
                res.append(currentValue);
            } else {
                res.append(currentValue + linkSymbol);
            }

        }
    }



}